/******************************************************************
 * @version      : 1.0
 * @Author       : zhl
 * @Date         : 2023-05-16 14:09:34
 * @LastEditors  : zhl
 * @E-Mail       : zhll168@163.com
 * @Description  : 业务描述
 ******************************************************************/
#include <functional>

#include "FileDownload.h"

FileDownload FileDownload::c_instance;


FileDownload::FileDownload(/* args */){
}

FileDownload::~FileDownload(){
}

FileDownload &FileDownload::getInstance(){
    return c_instance;
}

size_t FileDownload::write_to_file(void *contents, size_t size, size_t nmemb, FileDownload *fdownload){
    if((NULL == fdownload) || (NULL == fdownload->c_fp)){
        return 0;
    }
    size_t r_size = fwrite(contents, size, nmemb, fdownload->c_fp);
    fdownload->c_download_size += r_size;
    return r_size;
}

int FileDownload::progress(FileDownload *obj, double dltotal, double dlnow, double ultotal, double ulnow)  
{  
    if(NULL == obj){
        return 0;
    }
    FileDownload *fdownload = (FileDownload *)obj;
    if(1 > fdownload->c_total_size){
        fdownload->c_total_size = dltotal;
    }
 
    if (dltotal > -0.1 && dltotal < 0.1)  {
		return 0;
	}
    int nPos = (int) ((dlnow/dltotal)*100);  

 
    return 0;  
}

CURLcode FileDownload::init(const char *target, const char *username, const char *password){
    CURLcode error;
    c_fp = fopen(target, "w");
    if(NULL== c_fp){
        return CURLE_FTP_BAD_DOWNLOAD_RESUME;
    }
    char ftp_user_password[64] = {0};
    snprintf(ftp_user_password, sizeof(ftp_user_password), "%s:%s", username, password);
    c_download_size = 0;
    curl_global_init(CURL_GLOBAL_ALL);
    /* init the curl session */
    c_curl = curl_easy_init();
    /* send all data to this function */
    curl_easy_setopt(c_curl, CURLOPT_WRITEFUNCTION, write_to_file);
    /* we pass our 'chunk' struct to the callback function */
    curl_easy_setopt(c_curl, CURLOPT_WRITEDATA, this);
    curl_easy_setopt(c_curl, CURLOPT_NOPROGRESS, 0);  
    curl_easy_setopt(c_curl, CURLOPT_PROGRESSFUNCTION, progress);
    curl_easy_setopt(c_curl, CURLOPT_PROGRESSDATA, this);
    curl_easy_setopt(c_curl, CURLOPT_FOLLOWLOCATION, 1);

    curl_easy_setopt(c_curl, CURLOPT_USERPWD, ftp_user_password);
    curl_easy_setopt(c_curl, CURLOPT_FTP_RESPONSE_TIMEOUT, 3);
    curl_easy_setopt(c_curl, CURLOPT_FTPPORT, "-"); /* disable passive mode */
    curl_easy_setopt(c_curl, CURLOPT_FTP_CREATE_MISSING_DIRS, 1L);

    // https, skip the verification of the server's certificate.
    curl_easy_setopt(c_curl, CURLOPT_SSL_VERIFYPEER, 0L);
    curl_easy_setopt(c_curl, CURLOPT_SSL_VERIFYHOST, 0L);

    /* 设置连接超时,单位:毫秒 */
    curl_easy_setopt(c_curl, CURLOPT_CONNECTTIMEOUT_MS, 1000L);

    curl_easy_setopt(c_curl, CURLOPT_NOSIGNAL, 3);
    return CURLE_OK;
}

CURLcode FileDownload::download(std::string strUrl){
    CURLcode res;
    /* specify URL to get */
    curl_easy_setopt(c_curl, CURLOPT_URL, const_cast<char*>(strUrl.c_str()));
    //curl_easy_setopt(curl_handle, CURLOPT_URL, "http://10.66.91.15:7777/ld/smog/2612_src.jpg");

    c_download_size = 0;

    /* get it! */
    res = curl_easy_perform(c_curl);
    /* check for errors */
    if (res != CURLE_OK) {
        fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
        return CURLE_BAD_DOWNLOAD_RESUME;
    }
    else {
        /*
        * Now, our chunk.memory points to a memory block that is chunk.size
        * bytes big and contains the remote file.
        *
        * Do something nice with it!
        */
        printf("%lu bytes retrieved\n", (long)c_download_size);
    }
    return CURLE_OK;
}

void FileDownload::finish(){
    /* cleanup curl stuff */
    curl_easy_cleanup(c_curl);
    if(NULL != c_fp){
        fclose(c_fp);
        c_fp = NULL;
    }
    /* we're done with libcurl, so clean it up */
    curl_global_cleanup();
}